package nl.weeaboo.sh.io;

import static timon.common.xml.XmlUtil.getBoolean;
import static timon.common.xml.XmlUtil.getIdAttribute;
import static timon.common.xml.XmlUtil.getInt;
import static timon.common.xml.XmlUtil.getIntAttribute;
import static timon.common.xml.XmlUtil.getString;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import nl.weeaboo.sh.model.AreaModel;
import nl.weeaboo.sh.model.TileModel;
import nl.weeaboo.sh.model.TileSetIndex;
import nl.weeaboo.sh.model.TileSetModel;

import org.xml.sax.SAXException;

import timon.common.Log;
import timon.common.xml.XmlElement;
import timon.common.xml.XmlReader;

public class TileSetLoader {

	//Functions
	public TileSetModel load(AreaModel area, String path) throws IOException {
		FileInputStream fin = new FileInputStream(path);
		try {
			return load(area, fin);
		} finally {
			fin.close();
		}
	}
	public TileSetModel load(AreaModel area, InputStream in) throws IOException {		
		XmlReader reader = new XmlReader();
		XmlElement root;
		
		try {
			root = reader.read(in);
		} catch (SAXException e) {
			throw new RuntimeException(e);
		} catch (IOException e) {
			throw e;
		}	
		
		root = root.getChild("tileSet");
		if (root == null) {
			throw new RuntimeException(String.format("Root node not found (%s)", "tileSet"));
		}
		
		TileSetModel tileSet = new TileSetModel(getIdAttribute(root, "id"),
				getIntAttribute(root, "w", 0), getIntAttribute(root, "h", 0));
		area.addTileSet(tileSet);
		
		for (XmlElement e : root.elementChildren()) {
			if (tileSet.putTile(parseTile(area, e)) != null) {
				Log.warning("Overwriting a tile in a tileset during loading -- this should never happen");
			}
		}
		
		return tileSet;
	}
	protected TileModel parseTile(AreaModel area, XmlElement e) {
		TileModel tile;			
				
		String tagName = e.getTagName();
		if (tagName.equals("tile")) {
			tile = new TileModel();
		} else {
			Log.error("Unknown type of tile: " + tagName);
			return null;
		}
		
		XmlElement indexE = e.getChild("index");
		if (indexE != null) {
			TileSetIndex tsi = parseTileSetIndex(area, indexE);
			tile.setIndex(tsi);
		}
		
		XmlElement solidE = e.getChild("solidity");
		if (solidE != null) {
			tile.setSolidity(TileModel.Solidity.valueOf(solidE.getTextContent()));
		}

		tile.setClimbable(getBoolean(e, "climbable", false));
		tile.setBulletReflecting(getBoolean(e, "bulletReflecting", false));
		tile.setWallJumpable(getBoolean(e, "wallJumpable", false));
		tile.setWater(getBoolean(e, "water", false));
		
		tile.setFriction((byte)getInt(e, "friction", 0));
		tile.setHp((short)getInt(e, "hp", -1));
		tile.setDamage((short)getInt(e, "damage", 0));

		tile.setHeight0((byte)getInt(e, "h0", 0));			
		tile.setHeight1((byte)getInt(e, "h1", 0));			
		
		return tile;
	}
	
	public static TileSetIndex parseTileSetIndex(AreaModel area, XmlElement e) {
		return new TileSetIndex(area.getTileSet(getString(e, "tileSet")),
				getInt(e, "x", 0), getInt(e, "y", 0));
	}
		
	//Getters
	
	//Setters
	
}
